/*
 * Copyright 2009 Cedric Priscal
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */

package android_serialport_api;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.Iterator;
import java.util.LinkedList;

import android.R.string;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android_serialport_api.*;

//20201014 添加注释,移动辅助函数到工具类中

public  class ComPort {
	private static String TAG = "ComPort";

	protected SerialPort mSerialPort;
	protected OutputStream mOutputStream;
	private InputStream mInputStream;
	private ReadThread mReadThread;

	public String mComname;
	int boardRate = 115200;

	public interface DataHandler  {
		void onDataReceived(String comName, byte[] buffer, int size);
	}

	DataHandler dataHandler;

	private class ReadThread extends Thread {
		byte[] buffer = new byte[128];
		@Override
		public void run() {
			super.run();
			while(!isInterrupted()) {
				int size=0;
				try {
					if (mInputStream == null)
					    return;

					if( mInputStream!= null)
					size = mInputStream.read(buffer);

					if (size > 0) {
						onDataReceived(buffer, size);
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
			Log.i("Comport", "Com read thread exit.");
		}//end of run
	}//end of class ReadThread

	public ComPort()
	{
	}

	//防止切换activity后无法处理数据
	public void setHandler(DataHandler handler)
	{
		dataHandler = handler;
	}

	boolean isOpen = false;
	//串口使用3步骤 1.open 2.sendData 3.close 收到的数据会调用DataHandler
	public boolean open(String com_name, int boardRate, DataHandler handler) {
		dataHandler = handler;
		mComname = com_name;
		this.boardRate = boardRate;

		//防止重复打开
		if( isOpen ){
			Log.e("Comport", "this comport has opened.Don't open again or you should close before open.");
			return false;
		}

		try {
			if (mSerialPort == null) {
				mSerialPort = new SerialPort();
				boolean bOpen = mSerialPort.openPort(new File(mComname), boardRate, 0);
				if(bOpen== false)
					return bOpen;
			}

			if( mOutputStream == null)
				mOutputStream = mSerialPort.getOutputStream();

			if( mInputStream == null )
				mInputStream = mSerialPort.getInputStream();

			/* Create a receiving thread */
			if( mReadThread == null){
				mReadThread = new ReadThread();
				mReadThread.start();
			}
			isOpen = true;
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InvalidParameterException e) {
			e.printStackTrace();
		}

		return true;
	}

	public void close() {
		isOpen = false;

		try {
			if( mOutputStream != null){
				mOutputStream.close();
				mOutputStream = null;
			}

			if( mInputStream != null) {
				mInputStream.close();
				mInputStream = null;
			}
		}catch (IOException es)
		{

		}

		if (mReadThread != null){
			mReadThread.interrupt();
			mReadThread = null;
		}

		if (mSerialPort != null) {
			mSerialPort.close();
			mSerialPort = null;
		}
	}

	public void sendData(byte[] buffer, int size)
	{
		synchronized(this){
			try {
				//System.out.println("send to com" + bytes2HexString( buffer, size));
				if (mOutputStream != null) {
					mOutputStream.write(buffer,0, size);
					mOutputStream.flush();
				} else {
					return;
				}
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
	}

	//判断com口不为空
	private void onDataReceived(byte[] buffer, int size) {
		if( dataHandler !=null )
			dataHandler.onDataReceived(mComname, buffer, size );
	}
}
